<?php
// Copyright 2011 Zeptonic Ek. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
//    conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
//    of conditions and the following disclaimer in the documentation and/or other materials
//    provided with the distribution.
// 
// THIS SOFTWARE IS PROVIDED BY Zeptonic Ek ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Zeptonic Ek OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// 
// The views and conclusions contained in the software and documentation are those of the 
// authors and should not be interpreted as representing official policies, 
// either expressed or implied, of Zeptonic Ek.


/**
 * Basklass för hantering av sidförfrågningar.
 * 
 * @category Golfscraper
 * @package  Golfscraper
 * @author   Anders Axelsson <anders@zeptonic.com>
 * @author   Mattias Tiger <mattias@zeptonic.com>
 * @link     http://www.zeptonic.com
 */
abstract class Page {
	/**
	 * @var String Renderingsmaterial
	 */
	private $output;
	
	/**
	 * Startpunkt för hantering av sidförfrågan.
	 * Startar session, hanterar förfrågan samt renderar resultatet. 
	 *
	 * @return Void
	 */
	public function __construct() {
		session_start();
		$this->handle_request();
		echo $this->output;
	}
	
	/**
	 * Sätter renderingsmaterial.
	 *
	 * @param String $output Renderingsmaterial
	 *
	 * @return Void
	 */
	protected function set_output($output) {
		$this->output = $output;
	}
	
	/**
	 * Hanterar sidförfrågningen.
	 * Kontrollerar vilken typ av förfrågning som gjorts och anropar 
	 * rätt funktion för hantering.
	 * Typerna 'post'- och 'get'-förfrågningar är metoderna som stöds, 
	 * om annan metod använts skrivs ett felmeddelande ut.
	 *
	 * @return Void
	 */
	private function handle_request() {
		$sid = $this->get_session_id();
		$method = $_SERVER['REQUEST_METHOD'];
		switch($method) {
			case "GET":
				$this->handle_get_request($sid);
				break;
			case "POST":
				$this->handle_post_request($sid);
				break;
			default:
				die("Error: unsupported request method, " . $method);
		}
	}
	
	/**
	 * Hanterar sidförfrågning av typen 'get'.
	 * Olika hantering kan behövas beroende på vilket läge som 
	 * valts vid förfrågan. Läget fås från funktionen get_mode.
	 * Felaktiga lägen finns inte, alla definierade lägen hanteras 
	 * specifikt medan odefinierade lägen hanteras alla på samma sätt.
	 *
	 * @param String $sid Sessions-id
	 *
	 * @return Void
	 */
	private function handle_get_request($sid) {
		$mode = $this->get_mode();
		if($mode == MODE_VALUE_LOGIN) {
			$this->handle_get_login($sid);
		} elseif($mode == MODE_VALUE_LOGOUT) {
			$this->handle_get_logout($sid);
		} else {
			$this->handle_get_generic($sid);
		}
	}
	
	/**
	 * Implementeras för att hantera inloggning via förfrågningsmetoden 'get'.
	 *
	 * @param String $sid Sessions-id
	 *
	 * @return Void
	 *
	 * @abstract
	 */
	protected abstract function handle_get_login($sid);
	
	/**
	 * Implementeras för att hantera utloggning via förfrågningsmetoden 'get'.
	 *
	 * @param String $sid Sessions-id
	 *
	 * @abstract
	 */
	protected abstract function handle_get_logout($sid);
	
	/**
	 * Implementeras för att hantera generella fall via förfrågningsmetoden 'get'.
	 *
	 * @param String $sid Sessions-id
	 *
	 * @abstract
	 */
	protected abstract function handle_get_generic($sid);
	
	/**
	 * Implementeras för att hantera sidförfrågning av typen 'post'.
	 *
	 * @param String $sid Sessions-id
	 *
	 * @return Void
	 *
	 * @abstract
	 */
	protected function handle_post_request($sid) {
		$render_cmds = explode(",", $this->get_post_render_cmd());
		$cmd = $this->get_eventtarget();
		if($cmd == "none" || !in_array($cmd, $render_cmds)) {
			$this->handle_post_generic($sid);
		} else {
			$this->handle_post_render($sid);
		}
	}
	
	/**
	 * Implementeras för att hantera generella fall där formning av resultatet 
	 * krävs via förfrågningsmetoden 'post'.
	 *
	 * @param String $sid Sessions-id
	 *
	 * @return Void
	 *
	 * @abstract
	 */
	protected abstract function handle_post_render($sid);
	
	/**
	 * Implementeras för att hantera generella fall via förfrågningsmetoden 'post'.
	 *
	 * @param String $sid Sessions-id
	 *
	 * @abstract
	 */
	protected abstract function handle_post_generic($sid);
	
	/**
	 * Hämtar förfrågningsläget.
	 * Förfrågningslägen returneras med gemener och är definierat genom 
	 * querystring, dess nyckel definieras genom konstanten MODE_KEY.
	 * Om inget läge är definierat vid förfrågan returneras 'none'.
	 *
	 * @return String
	 */
	protected function get_mode() {
		if(isset($_GET[MODE_KEY])) {
			return strtolower($_GET[MODE_KEY]);
		}
		return "none";
	}
	
	/**
	 * Hämtar renderingskommando för post-förfrågningen.
	 * Om detta är ett värde skiljt från "none" betyder det att 
	 * formning ska ske av resultatet från skrapningen.
	 * 
	 * @return String
	 */
	protected function get_post_render_cmd() {
		if(isset($_GET[POST_RENDER_CMD_KEY])) {
			return strtolower($_GET[POST_RENDER_CMD_KEY]);
		}
		return "none";
	}
	
	/**
	 * Hämtar värdet från fältet __eventtarget som anger
	 * hur postförfrågan ska hanteras.
	 * Om inget värde kan hittas returneras "none". Detta sker
	 * då inget __eventtarget-fält är definierat eller
	 * då förfrågningsmetoden inte är post.
	 * 
	 * @return String
	 */
	protected function get_eventtarget() {
		$cmd = "none";
		if(isset($_POST['__EVENTTARGET'])) {
			$cmd = strtolower($_POST['__EVENTTARGET']);
		}
		return $cmd;
	}
	
	/**
	 * Hämtar sessions-id.
	 * Först kontrolleras om användaren har en cookie med sessions-id,
	 * och i så fall returneras detta. Annars hämtas ett 'nytt' sessions-id som
	 * genererades vid anrop till session_start() i konstruktorn och läggs
	 * i en cookie samt returneras.
	 * Cookie:n som skapas har namn och utgångstid som definieras genom
	 * konstanterna COOKIE_NAME och COOKIE_EXPIRE_TIME.
	 *
	 * @return String
	 */
	private function get_session_id() {
		if(isset($_COOKIE[COOKIE_NAME])) {
			return $_COOKIE[COOKIE_NAME];
		} else {
			$sid = session_id();
			setcookie(COOKIE_NAME, $sid, time() + COOKIE_EXPIRE_TIME);
			return $sid;
		}
	}
}
?>